/*=+--+=#=+--     Unmanned Aerial System Management Software      --+=#=+--+=#*\
|          Copyright (C) 2011 Regents of the University of Colorado.           |
|                             All Rights Reserved.                             |

     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License version 2 as
     published by the Free Software Foundation.

     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.

     You should have received a copy of the GNU General Public License
     along with this program.  If not, see <http://www.gnu.org/licenses/>.

            Jack Elston                       Cory Dixon                        
|           elstonj@colorado.edu              dixonc@colorado.edu              |
|                                                                              |
\*=+--+=#=+--                 --+=#=+--+=#=+--                    --+=#=+--+=#*/

/***********************************************************************
 *
 * FILENAME:
 * GPS.h
 *
 * PURPOSE:
 *  Provide gps inteface on MNR nodes and for VC.
 *
 * CREATED:
 * 02/2005 by Cory Dixon
 *
 * LAST MODIFIED:
 * $Author: dixonc $
 * $Date: 2005/11/02 20:27:20 $
 * $Revision: 1.4 $
 *
 ***********************************************************************/

#ifndef _GPS_H
#define _GPS_H

#include <string>
#include <vector>
#include <stdlib.h>

#include "commandStruct.h"

#define GPS_NUM_SATS       24

using namespace std;

typedef vector<string> VectorString;

// number of known NMEA commands
enum KnownNMEACommands { 
	GPGGA_CMD = 1,
	GPGLL_CMD,
	GPGSA_CMD,
	GPGSV_CMD,
	GPMSS_CMD,
	GPRMC_CMD,
	GPVTG_CMD,
	GPZDA_CMD,
	PUBX_CMD,
	PMCAG_CMD, 
	GPS_NUM_NMEA_CMDS
};

typedef struct _GPSSatView {
	uint8_t prn;
	float   elevation;
	float   azimuth;
	float   snr;
} GPSSatView;

typedef struct _GPS {
	float lat;        // deg
	float lon;        // deg
	float alt;        // m
	float speed;      // knots
	float track;      // ground heading deg from North
	float pdop;
	float hdop;
	float vdop;
	char  fix;

	//float   bearing;    // deg from north 
	//float   distance;   // m to waypoint   
	//float   deltaAlt;   // m to waypoint   
	//uint8_t waypointNum; // current waypoint

	unsigned long epochSec; // number of seconds since 0:0:0 UTC for today
	char          utc[10];  // hhmmss.ss
	char          date[7];  // ddmmyy
	uint8_t       quality;  // 0->invalid  1-> fix 2->DGPS
	uint8_t       sv;       // satellites in view
	GPSSatView    sats[GPS_NUM_SATS];
} GPS;

typedef struct _MGRS
{
	float    altitude;
	int      zoneNum;
	uint16_t gridEasting;
	uint16_t gridNorthing;
	char     zoneChar;
	char     colChar;
	char     rowChar;
} MGRS;

void GPSInit(GPS &gps);

// checksum, which is 8 bit xor of all values
// ignore $ (first character)
// go to * before checksum	 
uint8_t GPSCalcCheckSum(const char *cmd, int numChar);
string GPSCalcCheckSumStr(const char *cmd, int numChar);
uint8_t GPSCalcCheckSum(const string nmea);

// tokenize a string of characters into a 
// vector of tokens, split on the delimiters.
// For GPS, the default delimiters are ',' and '*'
void GPSstringTok(const string str, 
		VectorString & tokens, 
		const string& delimiters = ",*");

//
// Functions to parse NMEA commands
// from a Marconi GPS receiver
//
int processNMEA(GPS &gps, const char *buf );
void GPZDA(GPS &gps, VectorString & nmea);
void GPVTG(GPS &gps, VectorString & nmea);
void GPRMC(GPS &gps, VectorString & nmea);
void GPMSS(GPS &gps, VectorString & nmea);
void GPGSV(GPS &gps, VectorString & nmea);
void GPGSA(GPS &gps, VectorString & nmea);
void GPGLL(GPS &gps, VectorString & nmea);
void GPGGA(GPS &gps, VectorString & nmea);
void PUBX(GPS &gps, VectorString & nmea);
void PMCAG(GPS &gps, VectorString & nmea);

#endif
